// JavaScript source code
var mongo = require('mongodb').MongoClient;
var BSON = require('mongodb').BSONPure;

config = require('./config');

// helper function. Extends the string object to have an endsWith function
String.prototype.endsWith = function (suffix) {
    return this.indexOf(suffix, this.length - suffix.length) !== -1;
};

// PUT    <product-uri>/api/product/{prodId}/reviews/{reviewId}
exports.updateProductReview = function (req, res) {
    console.log("Got into updating product review");

    if (!req.body) {
        res.json({ error: "empty body" });
        return;
    }
    mongo.connect(config.dbUri, function (err, db) {

        // if there is an error during connection, return an error
        if (err) {
            res.json({ error: err });
            return;
        }
        // check that productID exists to allow write operation on review
        if (!req.params.productId) {
            res.json("Must have productID to insert reviews");
            return;
        }
        if (!req.params.reviewId) {
            res.json("Must have Review ID to insert reviews");
            return;
        }
        if (db) {

            var queryParams = {};
            queryParams.reviewId = BSON.ObjectID.createFromHexString(req.params.reviewId);

            req.body.productId = req.params.productId;
            db.collection('reviews').update({ _id: queryParams.reviewId }, req.body, function (err, inserted) {
                // when the insert is finished, this callback function is called
                if (err) {
                    res.json({ error: err });
                    return;
                }
                res.json(inserted);
                return;
            });
        }
    });

};

// POST   <product-uri>/api/product/{prodId}/reviews
exports.addProdReview = function (req, res) {
    console.log("entering method");
    if (!req.body) {
        res.json({ error: "empty body" });
        return;
    }

    mongo.connect(config.dbUri, function (err, db) {

        // if there is an error during connection, return an error
        if (err) {
            res.json({ error: err });
            return;
        }
        // check that productID exists to allow write operation on review
        if (!req.params.productId) {
            res.json("Must have productID to insert reviews");
            return;
        }
        if (db) {

            // console.log(req.body);
            // if there is no _id field in the object, Mongo will automatically create the _id
            // we read the body from the request and insert it in mongo

            req.body.productId = req.params.productId;
            //console.log(req.body);

            db.collection('reviews').insert(req.body, function (err, inserted) {
                // when the insert is finished, this callback function is called
                if (err) {
                    res.json({ error: err });
                    return;
                }

                res.json(inserted);
                return;
            });
        }
    });
};

// Implements the following REST interfaces
// GET    <product-uri>/api/product/{prodId}/reviews/{reviewId}
// GET    <product-uri>/api/product/{prodId}/reviews&pageIndex={index}&pageSize={size}
exports.getReviews = function (req, res) {
    mongo.connect(config.dbUri, function (err, db) {
        if (err) {
            console.log("error");
            return;
        }

        var queryParams = {};
        if (!req.params.productId) {
            req.json({ error: "no productId specified" });
            return;
        }

        queryParams.productId = req.params.productId;

        // single review
        if (req.params.reviewId) {
            console.log("review id is: " + req.params.reviewId);
            console.log("product id is: " + req.params.productId);
            queryParams._id = BSON.ObjectID.createFromHexString(req.params.reviewId);

            if (db) {
                db.collection('reviews', function (err, collection) {

                    // we pass the query parameters to the function. If you invoke without a query parameter,
                    // it will return everything
                    collection.find(queryParams).toArray(function (err, items) {
                        if (err) {
                            res.json({ error: err });
                        }

                        console.log(items);

                        // return the entire array as a JSON blob
                        // TODO: convert the names of the elements from input schema to output schema
                        res.json(items);
                        return;
                    });
                });
            }
        }

        // multiple paginated reviews
        if (req.route.path.endsWith("reviews")) {
            console.log("Into multiple pages");
            if (db) {
                db.collection('reviews', function (err, collection) {

                    var pageIndex = parseInt(req.query["pageIndex"]);
                    var pageSize = parseInt(req.query["pageSize"]);

                    if (isNaN(pageIndex) || isNaN(pageSize)) {
                        res.json({ error: "pageIndex or pageSize improperly specified" });
                        return;
                    }

                    // we pass the query parameters to the function. If you invoke without a query parameter,
                    // it will return everything
                    console.log(queryParams);
                    collection.find(queryParams)
                        .skip(pageIndex * pageSize) // the skip allows for pagination because we skip pageIndex*pageSize
                        .limit(pageSize) // pagesize limits how much to return in the result page
                        .toArray(function (err, items) {

                            if (err) {
                                res.json({ error: err });
                            }

                            var retObj = { totalCount: items.length, reviews: items }
                            // return the entire array as a JSON blob
                            // TODO: convert the names of the elements from input schema to output schema
                            res.json(retObj);
                            return;
                        });
                });
            }
        }
    });
};